'use strict';

const Service = require('ee-core').Service;
const Storage = require('ee-core').Storage;
const _ = require('lodash');
const path = require('path');
const { v4: uuidv4 } = require('uuid');

/**
 * 数据存储
 * @class
 */
class LocalStorageService extends Service {
  constructor(ctx) {
    super(ctx);
  }

  start() {
    this.sqliteFile = 'cesium-request-cache.sqlite.db';
    let sqliteOptions = {
      driver: 'sqlite',
      default: {
        timeout: 6000,
        verbose: console.log, // 打印sql语法
      },
    };
    this.demoSqliteDB = Storage.JsonDB.connection(this.sqliteFile, sqliteOptions);
  }

  /*
   * 检查并创建表 (sqlite)
   */
  async checkAndCreateTableSqlite(tableName = '') {
    if (_.isEmpty(tableName)) {
      throw new Error(`table name is required`);
    }

    // 查表规则
    let searchRule = '';
    let createRule = '';

    switch (tableName) {
      case 'task':
        searchRule = `SELECT * FROM sqlite_master WHERE type=? AND name = ?`;
        createRule = `CREATE TABLE ${tableName} (
            id text(50),
            state int(2),
            fileName text(100),
            progress text(50),
            isError int(10),
            remake text(100),
            filePath text(100),
            uploaded text(100),
            fileFullName text(100),
            isDeleted int(2),
            fileSize integer(100),
            uploadId text(50),
            uploadPath text(50),
            partSize int(50),
            lastPartSize int(50),
            partCount int(20),
            folderId text(50),
            uploadDir text(50),
            previewPath text(100),
            objectJson text(500),
            workid text(100),
            storagePath TEXT(100),
            PRIMARY KEY ("id")
          );`;
        break;

      case 'config':
        searchRule = 'SELECT * FROM task WHERE type=? AND name = ?';
        break;

      case 'mime':
        searchRule = 'SELECT * FROM task WHERE type=? AND name = ?';
        break;

      default:
        searchRule = '';
        break;
    }

    // 检查表是否存在
    const userTable = this.demoSqliteDB.db.prepare(searchRule);
    const result = userTable.get('table', tableName);
    if (result) return;

    this.demoSqliteDB.db.exec(createRule);
  }

  /*
   * 增 Test data (sqlite) 添加task
   */
  async addTaskDataSqlite(data) {
    let table = 'task';
    await this.checkAndCreateTableSqlite(table);

    const insert = this.demoSqliteDB.db.prepare(
      `INSERT INTO ${table} (id, state,fileName,progress,isError,remake,filePath,uploaded,fileFullName,isDeleted,fileSize,uploadId,uploadPath,partSize,lastPartSize,partCount,folderId,uploadDir,previewPath,objectJson,workid,storagePath) VALUES (@id, @state,@fileName,@progress,@isError,@remake,@filePath,@uploaded,@fileFullName,@isDeleted,@fileSize,@uploadId,@uploadPath,@partSize,@lastPartSize,@partCount,@folderId,@uploadDir,@previewPath,@objectJson,@workid,@storagePath)`
    );
    insert.run(data);
    return true;
  }

  /*
   * 删 Test data (sqlite)
   */
  async delTaskDataSqlite(id) {
    let table = 'task';
    await this.checkAndCreateTableSqlite(table);

    const delTask = this.demoSqliteDB.db.prepare(`DELETE FROM ${table} WHERE id = ?`);
    delTask.run(id);

    return true;
  }

  /*
   * 改 task data (sqlite)
   */
  async updateTaskDataSqlite(id = '', progress = 0) {
    let table = 'task';
    await this.checkAndCreateTableSqlite(table);
    const updateUser = this.demoSqliteDB.db.prepare(`UPDATE ${table} SET progress = ? WHERE id = ?`);
    updateUser.run(progress, id);
    return true;
  }

  /*
   * 查 Task data (sqlite) 所有
   */
  async getAllTaskDataSqlite() {
    let table = 'task';
    await this.checkAndCreateTableSqlite(table);
    const selectUser = this.demoSqliteDB.db.prepare(`SELECT * FROM ${table}`);
    const users = selectUser.all();
    return users;
  }

  /*
   * 查 Task data (sqlite) 根据id 查询单条数据
   */
  async getSingleTaskData(id) {
    let table = 'task';
    await this.checkAndCreateTableSqlite(table);
    const selectTask = this.demoSqliteDB.db.prepare(`SELECT * FROM ${table} WHERE id = ?`);
    const task = selectTask.all(id);
    return task;
  }

  /*
   * all Test data (sqlite)
   */
  async getAllTestDataSqlite() {
    let table = 'user';
    await this.checkAndCreateTableSqlite(table);
    const selectAllUser = this.demoSqliteDB.db.prepare(`SELECT * FROM ${table} `);
    const allUser = selectAllUser.all();
    //console.log("select allUser:", allUser);
    return allUser;
  }

  /*
   * get data dir (sqlite)
   */
  async getDataDir() {
    const dir = this.demoSqliteDB.getStorageDir();
    return dir;
  }

  /*
   * set custom data dir (sqlite)
   */
  async setCustomDataDir(dir) {
    if (_.isEmpty(dir)) {
      return;
    }

    // the absolute path of the db file
    const dbFile = path.join(dir, this.sqliteFile);
    const sqliteOptions = {
      driver: 'sqlite',
      default: {
        timeout: 6000,
        verbose: console.log,
      },
    };
    this.demoSqliteDB = Storage.JsonDB.connection(dbFile, sqliteOptions);

    return;
  }
}

LocalStorageService.toString = () => '[class LocalStorageService]';
module.exports = LocalStorageService;
